﻿module Sustainalytics.Navigation {

    import Routing = Sustainalytics.Routing;

    export class SiteMapNodeRouteResolverService implements ISiteMapNodeRouteResolverService {

        constructor(
            private $q: ng.IQService,
            private $routeParams: ng.route.IRouteParamsService,
            private $route: ng.route.IRouteService,
            private RoutingService: Routing.IRoutingService) {
        }

        public resolveNodeRoute(node: SiteMapNode): ng.IPromise<SiteMapNodeRoute> {
            var ctx = this;

            var def = ctx.$q.defer();

            if (node.path) {
                // get route for node path
                var route: Routing.ISecuredRoute = ctx.$route.routes[node.path];

                if (!route) {
                    console.log('Sustainalytics.Navigation :: Could not resolve route for node with Code: ' + node.code + ' Path: ' + node.path + ' Title: ' + node.title);
                }

                // format path
                var formattedPath = ctx.formatPath(node);

                if (route) {
                    // check route security
                    var promiseIsAllowed = ctx.checkRouteSecurity(node, route);

                    promiseIsAllowed.then(function (isAllowed) {
                        // create node route
                        var nodeRoute = new SiteMapNodeRoute(route, formattedPath, isAllowed);

                        def.resolve(nodeRoute);
                    });
                }
                else {
                    def.resolve(new SiteMapNodeRoute(route, formattedPath, false));
                }
            }
            else {
                def.resolve(null);
            }

            return def.promise;
        }

        private formatPath(node: SiteMapNode): string {
            var ctx = this;

            // format path according to route
            var formattedPath: string = '';

            if (ctx.$routeParams && ctx.$route.current) {

                formattedPath = node.path;

                for (var param in ctx.$route.current.params) {
                    var paramValue = ctx.$route.current.params[param];
                    formattedPath = formattedPath.replace(':' + param, paramValue);
                    formattedPath = formattedPath.replace(':' + param + '?', paramValue);
                }
            }

            return formattedPath;
        }

        private checkRouteSecurity(node: SiteMapNode, route: Routing.ISecuredRoute): ng.IPromise<boolean> {
            var ctx = this;

            var isAllowedPromise = ctx.RoutingService.validateRouteSecurity(route.security);

            return isAllowedPromise;
        }
    }


    export var siteMapNodeRouteResolverServiceName = 'SiteMapNodeRouteResolverService';

    angular.module(navigationModuleName).service(siteMapNodeRouteResolverServiceName, SiteMapNodeRouteResolverService);
}